<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="Generator" content="Kate, the KDE Advanced Text Editor" />
<title>whats_the_time.py</title>
</head>
<body>
<pre style='color:#141312;background-color:#ffffff;'>
<i><span style='color:#008000;'>#!/usr/bin/env python</span></i>

<i><span style='color:#008000;'>&quot;&quot;&quot;********************************************************************************</span></i>
<i><span style='color:#008000;'>                            whatsTheTime.py</span></i>
<i><span style='color:#008000;'>                 DAE Tools: pyDAE module, www.daetools.com</span></i>
<i><span style='color:#008000;'>                 Copyright (C) Dragan Nikolic, 2010</span></i>
<i><span style='color:#008000;'>***********************************************************************************</span></i>
<i><span style='color:#008000;'>DAE Tools is free software; you can redistribute it and/or modify it under the </span></i>
<i><span style='color:#008000;'>terms of the GNU General Public License as published by the Free Software </span></i>
<i><span style='color:#008000;'>Foundation; either version 3 of the License, or (at your option) any later version.</span></i>
<i><span style='color:#008000;'>The DAE Tools is distributed in the hope that it will be useful, but WITHOUT ANY </span></i>
<i><span style='color:#008000;'>WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A </span></i>
<i><span style='color:#008000;'>PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></i>
<i><span style='color:#008000;'>You should have received a copy of the GNU General Public License along with the</span></i>
<i><span style='color:#008000;'>DAE Tools software; if not, write to the Free Software Foundation, Inc., </span></i>
<i><span style='color:#008000;'>59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.</span></i>
<i><span style='color:#008000;'>********************************************************************************&quot;&quot;&quot;</span></i>

<i><span style='color:#008000;'>&quot;&quot;&quot;</span></i>
<i><span style='color:#008000;'>What is the time? (AKA Hello world!) is a very simple simulation. </span></i>
<i><span style='color:#008000;'>It shows the basic structure of the model and the simulation classes.</span></i>
<i><span style='color:#008000;'>A typical simulation imcludes 8 basic tasks:</span></i>
<i><span style='color:#008000;'>    1. How to import the pyDAE module</span></i>
<i><span style='color:#008000;'>    2. How to declare variable types</span></i>
<i><span style='color:#008000;'>    3. How to define a model by deriving a class from the base daeModel, what are the methods</span></i>
<i><span style='color:#008000;'>       that must be implemented by every model, and how to define an equation and its residual</span></i>
<i><span style='color:#008000;'>    4. How to define a simulation by deriving a class from the base daeDynamicSimulation, what are the methods</span></i>
<i><span style='color:#008000;'>       that must be implemented by every simulation, and how to set initial conditions</span></i>
<i><span style='color:#008000;'>    5. How to create auxiliary objects required for the simulation (DAE solver, data reporter and logging objects)</span></i>
<i><span style='color:#008000;'>    6. How to set simulation's additional settings</span></i>
<i><span style='color:#008000;'>    7. How to connect a data reporter</span></i>
<i><span style='color:#008000;'>    8. How to run a simulation</span></i>
<i><span style='color:#008000;'>&quot;&quot;&quot;</span></i>

<i><span style='color:#008000;'># 1. Import the modules</span></i>
<span style='color:#0000ff;'>import</span> sys
<span style='color:#0000ff;'>from</span> daetools.pyDAE <span style='color:#0000ff;'>import</span> <span style='color:#0000ff;'>*</span>
<span style='color:#0000ff;'>from</span> time <span style='color:#0000ff;'>import</span> localtime, strftime

<i><span style='color:#008000;'># 2. Define variable types</span></i>
<i><span style='color:#008000;'>#    Variable types are typically declared outside of model classes since they define common, reusable types.</span></i>
<i><span style='color:#008000;'>#    The daeVariable constructor takes 6 arguments:</span></i>
<i><span style='color:#008000;'>#     - Name: string</span></i>
<i><span style='color:#008000;'>#     - Units: string</span></i>
<i><span style='color:#008000;'>#     - LowerBound: float</span></i>
<i><span style='color:#008000;'>#     - UpperBound: float</span></i>
<i><span style='color:#008000;'>#     - InitialGuess: float</span></i>
<i><span style='color:#008000;'>#     - AbsoluteTolerance: float </span></i>
<i><span style='color:#008000;'>#    Here a very simple variable type is declared </span></i>
typeNone <span style='color:#0000ff;'>=</span> daeVariableType(<span style='color:#bf0303;'>&quot;None&quot;</span>, <span style='color:#bf0303;'>&quot;-&quot;</span>, <span style='color:#c000c0;'>0</span>, <span style='color:#c000c0;'>1E10</span>,   <span style='color:#c000c0;'>0</span>, <span style='color:#c000c0;'>1e-5</span>)

<i><span style='color:#008000;'># 3. Define a model</span></i>
<i><span style='color:#008000;'>#    New models are derived from the base daeModel class.</span></i>
<b>class</b> modTutorial(daeModel):
    <b>def</b> <b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>, Name, Parent <span style='color:#0000ff;'>=</span> <span style='color:#0000ff;'>None</span>, Description <span style='color:#0000ff;'>=</span> <span style='color:#bf0303;'>&quot;&quot;</span>):
        <i><span style='color:#008000;'># 3.1 Declare domains/parameters/variables/ports</span></i>
        <i><span style='color:#008000;'>#     Domains, parameters, variables, ports, etc has to be defined in the constructor: __init__</span></i>
        <i><span style='color:#008000;'>#     First, the base class constructor has to be called.</span></i>
        <i><span style='color:#008000;'>#     Then, all domains, parameters, variables, ports etc has to be declared as members of </span></i>
        <i><span style='color:#008000;'>#     the new model class (except equations which are handled by the framework), since the base class </span></i>
        <i><span style='color:#008000;'>#     keeps only their references. Therefore we write:</span></i>
        <i><span style='color:#008000;'>#                    self.variable = daeVariable(...) </span></i>
        <i><span style='color:#008000;'>#     and not:</span></i>
        <i><span style='color:#008000;'>#                    variable = daeVariable(...)</span></i>
        <i><span style='color:#008000;'>#</span></i>
        <i><span style='color:#008000;'>#     In this example we declare only one variable: time.</span></i>
        <i><span style='color:#008000;'>#     daeVariable constructor accepts 3 arguments:</span></i>
        <i><span style='color:#008000;'>#      - Name: string</span></i>
        <i><span style='color:#008000;'>#      - VariableType: daeVariableType</span></i>
        <i><span style='color:#008000;'>#      - Parent: daeModel object (indicating the model where the variable will be added)</span></i>
        <i><span style='color:#008000;'>#      - Description: string (optional argument - the variable description; the default value is an empty string)</span></i>
        <i><span style='color:#008000;'>#     Variable names can consists of letters, numbers, underscore ('_') and no other special characters (' ', '.', ',', '/', '-', etc).</span></i>
        <i><span style='color:#008000;'>#     However, there is an exception. You can use the standards html code names, such as Greek characters: &amp;alpha; &amp;beta; &amp;gamma; etc.</span></i>
        <i><span style='color:#008000;'>#     Internally they will be used without '&amp;' and ';' characters: alpha, beta, gamma, ...;</span></i>
        <i><span style='color:#008000;'>#     but, in the equations exported in the MathML or Latex format they will be shown as native Greek letters.</span></i>
        <i><span style='color:#008000;'>#     Also if you write the variable name as: Name_1 it will be transformed into Name with the subscript 1.</span></i>
        <i><span style='color:#008000;'>#     In this example we use Greek character 'tau' to name the variable 'time'.</span></i>
        daeModel.<b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>, Name, Parent, Description)
        <span style='color:#0000ff;'>self</span>.time <span style='color:#0000ff;'>=</span> daeVariable(<span style='color:#bf0303;'>&quot;&amp;tau;&quot;</span>, typeNone, <span style='color:#0000ff;'>self</span>, <span style='color:#bf0303;'>&quot;Time elapsed in the process, s&quot;</span>)

    <b>def</b> DeclareEquations(<span style='color:#0000ff;'>self</span>):
        <i><span style='color:#008000;'># 3.2 Declare equations and state transition networks</span></i>
        <i><span style='color:#008000;'>#     Here we declare only one equation. Equations are created by the function CreateEquation in daeModel class.</span></i>
        <i><span style='color:#008000;'>#     It accepts two arguments: equation name and description (optional). All naming conventions apply here as well.</span></i>
        <i><span style='color:#008000;'>#     Equations are written in the form of a residual, which is accepted by DAE equation system solvers:</span></i>
        <i><span style='color:#008000;'>#                           'residual expression' = 0</span></i>
        <i><span style='color:#008000;'>#     Residuals are defined by creating the above expression by using the basic mathematical operations (+, -, * and /) </span></i>
        <i><span style='color:#008000;'>#     and functions (sqrt, log, sin, cos, max, min, ...) on variables and parameters. Variables define several useful functions:</span></i>
        <i><span style='color:#008000;'>#      - operator () which calculates the variable value</span></i>
        <i><span style='color:#008000;'>#      - function dt() which calculates a time derivative of the variable</span></i>
        <i><span style='color:#008000;'>#      - function d() and d2() which calculate a partial derivative of the variable of the 1st and the 2nd order, respectively</span></i>
        <i><span style='color:#008000;'>#     In this example we simply write that the variable time derivative is equal to 1:</span></i>
        <i><span style='color:#008000;'>#                          d(time) / dt = 1</span></i>
        <i><span style='color:#008000;'>#     which calculates the time as the current time elapsed in the simulation (which is a common way to obtain the current time within the model).</span></i>
        <i><span style='color:#008000;'>#     Note that the variables should be accessed through the model object, therefore we use self.time</span></i>
        eq <span style='color:#0000ff;'>=</span> <span style='color:#0000ff;'>self</span>.CreateEquation(<span style='color:#bf0303;'>&quot;Time&quot;</span>, <span style='color:#bf0303;'>&quot;Differential equation to calculate the time elapsed in the process.&quot;</span>)
        eq.Residual <span style='color:#0000ff;'>=</span> <span style='color:#0000ff;'>self</span>.time.dt() <span style='color:#0000ff;'>-</span> <span style='color:#c000c0;'>1.0</span>
 
<i><span style='color:#008000;'># 4. Define a simulation</span></i>
<i><span style='color:#008000;'>#    Simulations are derived from the base daeDynamicSimulation class</span></i>
<b>class</b> simTutorial(daeDynamicSimulation):
    <b>def</b> <b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>):
        <i><span style='color:#008000;'># 4.1 First, the base class constructor has to be called, and then the model for the simulation has to be instantiated.</span></i>
        <i><span style='color:#008000;'>#     daeDynamicSimulation class has three properties used to store the model: 'Model', 'model' and 'm'.</span></i>
        <i><span style='color:#008000;'>#     They are absolutely equivalent, and user can choose which one to use. For clarity, I prefer the shortest one: m.</span></i>
        daeDynamicSimulation.<b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>)
        <span style='color:#0000ff;'>self</span>.m <span style='color:#0000ff;'>=</span> modTutorial(<span style='color:#bf0303;'>&quot;WhatsTheTime&quot;</span>)
        <span style='color:#0000ff;'>self</span>.m.Description <span style='color:#0000ff;'>=</span> <span style='color:#bf0303;'>&quot;What is the time? (AKA Hello world) is the simplest simulation. It shows the basic structure of the model and the simulation classes. &quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;The basic 8 steps are explained: </span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;1. How to import pyDAE module </span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;2. How to declare variable types </span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;3. How to define a model by deriving a class from the base daeModel, etc </span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;4. How to define a simulation by deriving a class from the base daeDynamicSimulation, etc </span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;5. How to create auxiliary objects required for the simulation (DAE solver, data reporter and logging objects) </span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;6. How to set simulation's additional settings </span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;7. How to connect the TCP/IP data reporter </span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;8. How to run a simulation </span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span>
          
    <b>def</b> SetUpParametersAndDomains(<span style='color:#0000ff;'>self</span>):
        <i><span style='color:#008000;'># 4.2 Define the domains and parameters</span></i>
        <i><span style='color:#008000;'>#     Every simulation class must implement SetUpParametersAndDomains method, even if it is empty.</span></i>
        <i><span style='color:#008000;'>#     It is used to set the values of the parameters, create domains etc. In this example nothing has to be done.</span></i>
        <b>pass</b>
    
    <b>def</b> SetUpVariables(<span style='color:#0000ff;'>self</span>):
        <i><span style='color:#008000;'># 4.3 Set initial conditions, initial guesses, fix degreees of freedom, etc.</span></i>
        <i><span style='color:#008000;'>#     Every simulation class must implement SetUpVariables method, even if it is empty.</span></i>
        <i><span style='color:#008000;'>#     In this example the only thing needed to be done is to set the initial condition for the variable time to 0.</span></i>
        <i><span style='color:#008000;'>#     That can be done by using SetInitialCondition function:</span></i>
        <span style='color:#0000ff;'>self</span>.m.time.SetInitialCondition(<span style='color:#c000c0;'>0</span>)

<i><span style='color:#008000;'># Use daeSimulator class</span></i>
<b>def</b> guiRun():
    <span style='color:#0000ff;'>from</span> PyQt4 <span style='color:#0000ff;'>import</span> QtCore, QtGui
    app <span style='color:#0000ff;'>=</span> QtGui.QApplication(sys.argv)
    simulation <span style='color:#0000ff;'>=</span> simTutorial()
    simulation.m.SetReportingOn(<span style='color:#0000ff;'>True</span>)
    simulation.ReportingInterval <span style='color:#0000ff;'>=</span> <span style='color:#c000c0;'>10</span>
    simulation.TimeHorizon       <span style='color:#0000ff;'>=</span> <span style='color:#c000c0;'>1000</span>
    simulator  <span style='color:#0000ff;'>=</span> daeSimulator(app, simulation)
    simulator.show()
    app.exec_()

<i><span style='color:#008000;'># Setup everything manually and run in a console</span></i>
<b>def</b> consoleRun():
    <i><span style='color:#008000;'># 5.Create Log, Solver, DataReporter and Simulation object</span></i>
    <i><span style='color:#008000;'>#   Every simulation requires the following four objects:</span></i>
    <i><span style='color:#008000;'>#    - log is used to send the messages from other parts of the framework, informs us about the simulation progress or errors</span></i>
    <i><span style='color:#008000;'>#    - solver is DAE solver used to solve the underlying system of differential and algebraic equations</span></i>
    <i><span style='color:#008000;'>#    - datareporter is used to send the data from the solver to daePlotter</span></i>
    <i><span style='color:#008000;'>#    - simulation object</span></i>
    log          <span style='color:#0000ff;'>=</span> daePythonStdOutLog()
    solver       <span style='color:#0000ff;'>=</span> daeIDASolver()
    datareporter <span style='color:#0000ff;'>=</span> daeTCPIPDataReporter()
    simulation   <span style='color:#0000ff;'>=</span> simTutorial()

    <i><span style='color:#008000;'># 6. Additional settings</span></i>
    <i><span style='color:#008000;'># Here some additional information can be entered. The most common are:</span></i>
    <i><span style='color:#008000;'>#  - TimeHorizon: the duration of the simulation</span></i>
    <i><span style='color:#008000;'>#  - ReportingInterval: the interval to send the variable values</span></i>
    <i><span style='color:#008000;'>#  - Selection of the variables which values will be reported. It can be set individually for each variable by using the property var.ReportingOn = True/False,</span></i>
    <i><span style='color:#008000;'>#    or by the function SetReportingOn in daeModel class which enables reporting of all variables in that model</span></i>
    simulation.TimeHorizon <span style='color:#0000ff;'>=</span> <span style='color:#c000c0;'>500</span>
    simulation.ReportingInterval <span style='color:#0000ff;'>=</span> <span style='color:#c000c0;'>10</span>
    simulation.m.SetReportingOn(<span style='color:#0000ff;'>True</span>)

    <i><span style='color:#008000;'># 7. Connect the data reporter</span></i>
    <i><span style='color:#008000;'>#    daeTCPIPDataReporter data reporter uses TCP/IP protocol to send the results to the daePlotter.</span></i>
    <i><span style='color:#008000;'>#    It contains the function Connect which accepts two arguments:</span></i>
    <i><span style='color:#008000;'>#      - TCP/IP address and port as a string in the following form: '127.0.0.1:50000'. </span></i>
    <i><span style='color:#008000;'>#        The default is an empty string which allows the data reporter to connect to the local (on this machine) daePlotter listening on the port 50000.</span></i>
    <i><span style='color:#008000;'>#      - Process name; in this example we use the combination of the simulation name and the current date and time</span></i>
    simName <span style='color:#0000ff;'>=</span> simulation.m.Name <span style='color:#0000ff;'>+</span> strftime(<span style='color:#bf0303;'>&quot; [</span><span style='color:#0000ff;'>%d</span><span style='color:#bf0303;'>.%m.%Y %H:%M:%S]&quot;</span>, localtime())
    <b>if</b>(datareporter.Connect(<span style='color:#bf0303;'>&quot;&quot;</span>, simName) <span style='color:#0000ff;'>==</span> <span style='color:#0000ff;'>False</span>):
        sys.exit()

    <i><span style='color:#008000;'># 8. Run the simulation</span></i>
    <i><span style='color:#008000;'>#  8.1 The simulation initialization</span></i>
    <i><span style='color:#008000;'>#      The first task is to initialize the simulation by calling the function Initialize.</span></i>
    <i><span style='color:#008000;'>#      After the successful initialization the model report can be saved.</span></i>
    <i><span style='color:#008000;'>#      The function SaveModelReport exports the model report in the XML format which can be opened in a web browser </span></i>
    <i><span style='color:#008000;'>#      (like Mozilla Firefox, or others that support XHTML+MathMl standard).</span></i>
    <i><span style='color:#008000;'>#      The function SaveRuntimeModelReport creates a runtime sort of the model report (with the equations fully expanded)</span></i>
    simulation.Initialize(solver, datareporter, log)

    simulation.m.SaveModelReport(simulation.m.Name <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;.xml&quot;</span>)
    simulation.m.SaveRuntimeModelReport(simulation.m.Name <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;-rt.xml&quot;</span>)

    <i><span style='color:#008000;'>#  8.2 Solve at time = 0 (initialization)</span></i>
    <i><span style='color:#008000;'>#      The DAE system must be first initialized. The function SolveInitial is used for that purpose.</span></i>
    simulation.SolveInitial()

    <i><span style='color:#008000;'># 8.3 Finally, the function Run from the daeDynamicSimulation class is called to start the simulation.</span></i>
    <i><span style='color:#008000;'>#     It will last for TimeHorizon seconds and the results will be reported after every ReportingInterval number of seconds </span></i>
    simulation.Run()

<i><span style='color:#008000;'># This part of the code executes if the python script is executed from a shell</span></i>
<i><span style='color:#008000;'># 1) If you use: &quot;python whats_the_time.py console&quot; the simulation will be launched from the console</span></i>
<i><span style='color:#008000;'># 2) If you use: &quot;python whats_the_time.py gui&quot; the simulation will be launched from a GUI</span></i>
<i><span style='color:#008000;'>#    The default is &quot;gui&quot; and you can omit it.</span></i>
<b>if</b> <b><span style='color:#000000;'>__name__</span></b> <span style='color:#0000ff;'>==</span> <span style='color:#bf0303;'>&quot;__main__&quot;</span>:
    runInGUI <span style='color:#0000ff;'>=</span> <span style='color:#0000ff;'>True</span>
    <b>if</b> <b><span style='color:#000000;'>len</span></b>(sys.argv) <span style='color:#0000ff;'>&gt;</span> <span style='color:#c000c0;'>1</span>:
        <b>if</b>(sys.argv[<span style='color:#c000c0;'>1</span>] <span style='color:#0000ff;'>==</span> <span style='color:#bf0303;'>'console'</span>):
            runInGUI <span style='color:#0000ff;'>=</span> <span style='color:#0000ff;'>False</span>
    <b>if</b> runInGUI:
        guiRun()
    <b>else</b>:
        consoleRun()
</pre>
</body>
</html>
